iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0
自我挑戰組

Do you wanna play? CSS game ぎりぎり系列 第 30

[Day 30] Iron 30 Dashboard: 鐵人参拾儀表板

  • 分享至 

  • xImage
  •  

今天是第30天 ~
好的各位,我在前幾天的努力之下,做了個儀表板整合前面每天的作品 ~ 總共實作了27個作品
其實整合儀表板的想法從一開始就有了XD,就是一個趕死線仔

Iron 30 Dashboard

一般螢幕:

較小螢幕:

Demo: https://iron30.netlify.app/
Code: https://github.com/Stevetanus/CSS100

RWD與UI配色的部分沒有達到專業的部分,仍持續在試錯與學習,我盡我目前所能做出現階段的鐵人參拾儀表板。

這個儀表板是使用React框架,個人還是初學階段,寫法不是目前的常見寫法,例如: 不會在App.js裡面塞入那麼多程式碼,JavaScript寫法可以改成Hooks等等;而這是我覺得較快能夠整合的方法。跟著此份文件無法直接完成作品,但我會介紹我如何將每天的實作放進去,來讓大家透過dashboard看到作品、切換作品、連結到文章和程式碼


作品架構

https://ithelp.ithome.com.tw/upload/images/20221007/20152191qCOVpuw5FM.png
Components有day1~day27的folder,放著27天實作的元件,我們從主元件App.js中如何建立路徑開始,再來介紹其中一天的元件(Day7.js)如何建立。

App.js

import {
  BrowserRouter,
  NavLink,
  Routes,
  Route,
  Navigate,
} from "react-router-dom"; <!-- 匯入套件 -->
import Day1 from "./components/day1/Day1"; <!-- Day1元件 -->
import Day7 from "./components/day7/Day7"; <!-- Day7元件 -->

function App() {
  ...
  return (
    <BrowserRouter> <!-- App元件回傳BrowserRouter -->
      <h1>Welcome to Iron 30 dashboard \(^Д^)/</h1>
      <div className="leftside_nav"> // 左側navbar 
        let activeClassName = "nav-active";
        ...
        ...
          <!-- 以day1跟day7當範例,下面NavLink可以連結到to="路徑"的元件,而路徑在下方Routes定義 -->
          <NavLink
            to="day1"
            <!-- 選到的元素會有`.nav-active`的class -->
            className={({ isActive }) =>
              isActive ? activeClassName : undefined
            }
          >
            <div className="daybar">
              <span>1</span>
            </div>
          </NavLink>
          <NavLink
            to="day7"
            className={({ isActive }) =>
              isActive ? activeClassName : undefined
            }
          >
            <div className="daybar">
              <span>7</span>
            </div>
          </NavLink>
         
        <div className="back" onClick={toggleHome}> <!-- 回首頁 -->
          <NavLink className={home ? "none" : "back"} to="back">
            Back
          </NavLink>
        </div>
      </div>
      <div className="bottom_nav"> <!-- 下方連結 -->
        <span>
          Made by{" "}
          <a
            target="_blank"
            rel="noreferrer"
            href="https://github.com/Stevetanus/CSS100/"
          >
            steventhibe
          </a>
        </span>
        <span>
          Inspired by{" "}
          <a target="_blank" rel="noreferrer" href="https://100dayscss.com/">
            CSS 100
          </a>
        </span>
      </div>

      <Routes> <!-- 定義路徑 -->
        <Route path="/" element={<Home />} />
        <Route path="day1" element={<Day1 />} /> <!-- 連接到Day1元件 -->
        <Route path="day7" element={<Day7 />} /> <!-- 連接到Day7元件 -->
        <Route path="back" element={<Navigate to="/" />} /> <!-- 連回到首頁 -->
      </Routes>
    </BrowserRouter>
  );
}

這邊我們以Day7當作範例,App.js會回傳BrowserRouter,裡面要有Routes連結到Day7.js,然後有NavLink可以去選擇這個路徑呈現Day7.js的元件。

Routing With React Router 6

index.scss

@import url(https://fonts.googleapis.com/css?family=Open+Sans:700,300,400,500,600,200,800);

.frame {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 400px;
  height: 400px;
  margin-top: -200px;
  margin-left: -200px;
  border-radius: 2px;
  box-shadow: 4px 8px 16px 0 rgba(0, 0, 0, 0.1);
  overflow: hidden;
  background: #fff;
  color: #333;
  font-family: "Open Sans", Helvetica, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

將template配置的.frame.center寫進去,所有App內的元件都可以套用,之後再依照day的變化,來給予不同的class,加入不同天的屬性。


Day7.js

https://ithelp.ithome.com.tw/upload/images/20221007/20152191sXeVBOUIGA.jpg
在components的資料夾中,有著day1~day27的資料夾,day7的資料夾為以上所示,裡面有Day7.js,與其要連結的css檔案等。

import React, { useEffect } from "react";
import toggle from "../function/toggle";
import "./day7.css";

export default function Day7() {
  useEffect(() => {
    const searchInput = document.querySelector(".search-input");
    const searchIcon = document.querySelector(".search-icon");
    searchIcon.addEventListener("click", () => {
      searchInput.classList.toggle("active");
    });
    const menuIcon = document.querySelector(".menu-icon");
    const panel = document.querySelector(".panel_d7");
    const menu = document.querySelector(".menu_d7");
    menuIcon.addEventListener("click", () => {
      panel.classList.toggle("show-menu");
      menu.classList.toggle("active");
    });
    toggle();
  }, []); <!-- 會在元件render後執行一次,就一次 -->

  return (
    <>
      <!-- .frame的元素我會再加入.day7類似的class -->
      <div className="frame day7"> <!-- 所有HTML可直接放入,需要再小修一點,像是class要改成className -->
        <!-- .frame內部較為外層的元素會加上_d7用來區隔的class -->
        <div className="panel_d7">
          ...
        </div>

        <div className="menu_d7">
          ...
        </div>
      </div>
      <div className="css100_description"> <!-- 右側的解說欄 -->
        <h3>Notifications, Search and Menu</h3>
        <p>
          The three cornerstones of any application? Brought together in the
          smallest possible space.
        </p>
        <p>
          <a
            className="reflink"
            target="_blank"
            rel="noreferrer"
            href="https://ithelp.ithome.com.tw/articles/10291130" <!-- 鐵人賽文章連結 -->
          >
            Iron article
          </a>
          <a
            className="reflink"
            target="_blank"
            rel="noreferrer"
            href="https://codepen.io/stevetanus/pen/abGBrxo" <!-- CodePen連結 -->
          >
            Source
          </a>
        </p>
      </div>
      <div className="menu_right"> <!-- 在小畫面時,會出現在右邊的選單,用來開合解說欄 -->
        <i class="fa-solid fa-arrow-left"></i>
      </div>
    </>
  );
}

在Day7.js中,我們在return的地方放入原本的HTML,需要對於class做些修改以防出現重疊的class屬性,在useEffect內放入原本的JavaScript,並設定第二個參數為[],讓此函式在元件render後只執行一次。

再來看到SCSS:

$blue_d7: #5f98cd;
$blue-dark: #264057;
$blue-light: #b2daff;

<!-- 透過設定跟day7相關的class來讓屬性套用不會重疊,因為前面.frame有在index.scss定義過,所以只需要加入Day7.js獨特的屬性,像是背景、陰影、文字顏色,還有該作品的SCSS。 -->
.day7 {
  box-shadow: 1px 2px 10px 0px rgba(0, 0, 0, 0.3);
  background: $blue-dark;
  color: #666;
}

.panel_d7{...
}

.menu_d7{...
}

@keyframes ...

小結

從上面的程式配置,我們可以知道每天的實作要如何變成React元件,並透過React Router 6來達到切換,而一些所有元素都需要的屬性我們在index.scss定義,其他則是在元件該資料夾中的SCSS中定義,方便我們未來進行修改,再來就是些排版的功夫,從前面的實作中累積些CSS的技巧應用在上面,而在create-react-app的網頁App中非常方便的是,我們可以在修改後即時看畫面呈現的情況為何,再去進行調整。最後,完成作品我們上傳到github,透過netlify來上架我們的網站,詳細流程可以參考下方連結。

另外,我覺得CSS100的好處除了讓你從高手的作品中去練習CSS,也給你了一些對於網頁元素組合的想像,你可以在實作中加入你的變化,或是串聯起兩三個實作在你的個人作品之中,形成你自己的風格並為你加分。

netlify上架文章: https://ithelp.ithome.com.tw/articles/10257115


緣起與結尾

正如我在Day29所述,我想到一個好的主題且接觸到許多網路大大的好文章是我報名參加鐵人賽的契機,至於為什麼我的標題會是Do you wanna play? CSS game ぎりぎり呢?

既然我誠心誠意的發問了,那我就回答自己~因為開賽前有首歌叫做新時代(航海王劇場版主題曲)很好聽,那陣子一直聽一直聽,就覺得ぎりぎり這個詞兒怎麼那麼上耳,後來就把那句歌詞「"Do you wanna play? リアルゲーム ギリギリ"」改成這個系列文的標題了 ~ XDD

在這30天的挑戰中,因為沒有儲備文章的關係,每天都要回家寫文章,一開始有些不適應,隨著時間積累有逐漸習慣,且我覺得我此次挑戰主題十分明確,不至於出現不知道寫什麼或是亂寫的情況,倒是會省略些CSS重複或瑣碎的部分,我比較擔心的是如果不小心確診的話,可能會使得挑戰中斷,非常幸運地能夠健健康康的產出文章,當然離圖文並茂的文章還很遠,還是開心地學習並分享CSS的技巧給大家。

當初開賽的時候就想說,中秋或國慶連假其中一個一定會犧牲掉,所以國慶連假就要好好地出去玩啦!感謝各位的收看,Thibe跟大家說掰掰 ~ 那...也許我們明年再見(ゝ∀・)b


上一篇
[Day 29] Checklist: 打個勾勾完賽吧
系列文
Do you wanna play? CSS game ぎりぎり30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言